
/*
 * @Author: aggfb 714740235@qq.com
 * @Date: 2024-12-22 20:11:14
 * @LastEditors: aggfb 714740235@qq.com
 * @LastEditTime: 2025-07-17 07:43:01
 * @FilePath: \wire_receiver_collect_box\communication\com_lora.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "com_lora.h"
#include "crc16.h"
#include "SEGGER_RTT.h"
#include "bsp_uart.h"

#include <string.h>

#define FREAME_HANDER_AD 0xAD
#define FREAME_HANDER_DA 0xDA

struct master_lora_drv master_lora = {

};

static uint8_t com_lora_recv_null(uint8_t *buff, uint8_t len) { return 0; }
static uint8_t com_lora_recv_driver1(uint8_t *buff, uint8_t len); // 从动盘总机1
static uint8_t com_lora_recv_driver2(uint8_t *buff, uint8_t len); // 从动盘总机2

static uint8_t com_lora_recv_out_terminal1(uint8_t *buff, uint8_t len); // 收线器1
static uint8_t com_lora_recv_out_terminal2(uint8_t *buff, uint8_t len); // 收线器2

static uint8_t com_lora_recv_key1(uint8_t *buff, uint8_t len); // 按键板反馈1
static uint8_t com_lora_recv_key2(uint8_t *buff, uint8_t len); // 按键板反馈2

typedef uint8_t (*function)(uint8_t *buff, uint8_t len);
static const function list_cmd_function[7] = {
    com_lora_recv_null,
    com_lora_recv_driver1,
    com_lora_recv_driver2,
    com_lora_recv_out_terminal1,
    com_lora_recv_out_terminal2,
    com_lora_recv_key1,
    com_lora_recv_key2,
};

///////////////////////////////////////////////////////////////////////////////////////
//                 以下是接收数据处理
///////////////////////////////////////////////////////////////////////////////////////
/* 从动盘总机1 来的数据 */
static struct box_drv_info collect_box1[3];
#define DIFF_RPM_COUNT 100
static uint8_t com_lora_recv_driver1(uint8_t *buff, uint8_t len)
{
    SEGGER_RTT_printf(0, "lora 1.\r\n");
    static uint8_t count = 0;
    if (count++ >= 3)
    {
        count = 0;
    }
    memcpy((uint8_t *)(&collect_box1[count].drv_info), buff, sizeof(struct slave_drv_info) * 15 - 1);
    for (uint8_t i = 0; i < 15; i++)
    {
        for (uint8_t j = 0; j < 3; j++)
        {
            if (abs(collect_box1[j].drv_info[i].rpm - collect_box1[j + 1].drv_info[i].rpm) >= DIFF_RPM_COUNT)
            {
                master_lora.driven_plate[0].box_bits |= (0x00001 << i);
            }
        }
    }
    return 0;
}

/* 从动盘总机2 来的数据 */
static struct box_drv_info collect_box2[3];
static uint8_t com_lora_recv_driver2(uint8_t *buff, uint8_t len)
{
    SEGGER_RTT_printf(0, "lora 2.\r\n");
    static uint8_t count = 0;
    if (count++ >= 3)
    {
        count = 0;
    }
    memcpy((uint8_t *)(&collect_box2[count].drv_info), buff, sizeof(struct slave_drv_info) * 15 - 1);
    for (uint8_t i = 0; i < 15; i++)
    {
        for (uint8_t j = 0; j < 3; j++)
        {
            if (abs(collect_box2[j].drv_info[i].rpm - collect_box2[j + 1].drv_info[i].rpm) >= DIFF_RPM_COUNT)
            {
                master_lora.driven_plate[1].box_bits |= (0x00001 << i);
            }
        }
    }
    return 0;
}

/* 收线器1 */
static uint8_t com_lora_recv_out_terminal1(uint8_t *buff, uint8_t len)
{
    memcpy((uint8_t *)(&master_lora.calculate_line[0]), buff, sizeof(struct calculate_line_drv));
    SEGGER_RTT_printf(0, "lora out1[%d; %d ;%d]\r\n", sizeof(struct calculate_line_drv),
                      master_lora.calculate_line[0].addr,
                      master_lora.calculate_line[0].plus);

    /* 通过编码器的值计算已经收线长度 */
    master_lora.drv1_len_m = (double)master_lora.calculate_line[0].plus * UNIT_PLUS_DISTANCE;
    if (master_lora.drv1_len_m <= 0.001f)
    {
        master_lora.drv1_len_m = 0 - master_lora.drv1_len_m;
    }
    return 0;
}

/* 收线器2 */
static uint8_t com_lora_recv_out_terminal2(uint8_t *buff, uint8_t len)
{
    memcpy((uint8_t *)(&master_lora.calculate_line[1]), buff, sizeof(struct calculate_line_drv));
    SEGGER_RTT_printf(0, "lora out2=%d; %d ; %d.\r\n", sizeof(struct calculate_line_drv),
                      master_lora.calculate_line[1].addr,
                      master_lora.calculate_line[1].plus);

    /* 通过编码器的值计算已经收线长度 */
    master_lora.drv2_len_m = (double)master_lora.calculate_line[1].plus * UNIT_PLUS_DISTANCE;
    if (master_lora.drv2_len_m <= 0.001f)
    {
        master_lora.drv2_len_m = 0 - master_lora.drv2_len_m;
    }
    return 0;
}

/* 按键板反馈1 */
static uint8_t com_lora_recv_key1(uint8_t *buff, uint8_t len)
{
    SEGGER_RTT_printf(0, "lora key[%d; %d; %d;].\r\n",buff[0], buff[1], buff[2]);
    master_lora.key[0].start_sta = buff[0];
    master_lora.key[0].slow_sta = buff[1];
    master_lora.key[0].stop_sta = buff[2];
    return 0;
}

/* 按键板反馈2 */
static uint8_t com_lora_recv_key2(uint8_t *buff, uint8_t len)
{
    SEGGER_RTT_printf(0, "lora 6.\r\n");
    memcpy((uint8_t *)(&master_lora.key[1]), buff, sizeof(struct key_drv) - 1);
    return 0;
}

void lora_receive_analysis(uint8_t byte)
{
    static uint8_t number = 0;
    static uint8_t pos = 0;
    static uint8_t buff[128U] = {0};
    static uint8_t size = 0;

LAB_ANALYSIS:
    switch (number)
    {
    case 0: /* 找帧头1 */
        if (FREAME_HANDER_AD == byte)
        {
            number = 1;
            pos = 0;
            buff[pos++] = byte;
        }
        break;
    case 1: /* 找帧头2 */
        if (FREAME_HANDER_DA == byte)
        {
            number = 2;
            buff[pos++] = byte;
        }
        else
        {
            number = 0;
            goto LAB_ANALYSIS;
        }
        break;
    case 2: /* 获取地址 */
        buff[pos++] = byte;
        /* 总机目标地址 0x06 */
        if ((byte & 0xF0) == 0x60)
        {
            number = 3;
        }
        else
        {
            number = 0;
        }
        break;
    case 3: /* 获取长度 */
        size = byte;
        buff[pos++] = byte;
        number = 4;
        break;
    case 4: /* 获取类型 */
        buff[pos++] = byte;
        number = 5;
        break;
    case 5: /* 获取数据 */
        buff[pos++] = byte;
        if (pos >= 0xff) /* 超界检测 */
        {
            number = 0;
            break;
        }
        if (pos >= (size + 4 + 1 + 2)) /* +2是为了获取校验 */
        {
            uint16_t crc = crc16_checksum(&buff[4], (size + 1));
            if (crc == ((buff[(size + 4 + 1)] << 8) | buff[(size + 4 + 2)]))
            {
                switch (buff[2])
                {
                case 0x60:
                    com_lora_recv_key1(&buff[5], size);
                    break;
                case 0x61:
                    com_lora_recv_out_terminal1(&buff[5], size);
                    break;
                case 0x64:
                    com_lora_recv_out_terminal2(&buff[5], size);
                    break;
                }
            }
#if 0
					for(uint8_t i = 0; i < (size+4+1+2); i++)
					{
						SEGGER_RTT_printf(0, "crc = 0x%x;; 0x%x;]\r\n", crc, buff[i]);
					}
#endif
            number = 0;
        }
        break;
    default:
        break;
    }
}

/*******************************************************************
 * 函数名: com_lora_send_cmd()
 * 功 能: 循环 给lora从机发送上报数据消息
 * 输 入:
 *
 * 输 出:
 *******************************************************************/
static struct _protocol pack;
int16_t com_lora_send_cmd(uint8_t slave_id, uint8_t data)
{
    pack.buff[0] = FREAME_HANDER_AD;
    pack.buff[1] = FREAME_HANDER_DA;
    pack.buff[2] = 0x06 | (slave_id << 4); /* 地址 高4位为目标地址 低4位为发出地址 */
    pack.buff[3] = 0x04;                   /* 长度 */
    pack.buff[4] = 0x01;                   /* 类型 */
    pack.buff[5] = data;                   /* 预留 */
    pack.buff[6] = pack.buff[5];           /* crc l */
    pack.buff[7] = 0x00;                   /* crc h */
    pack.size = 8;

    bsp_uart_driver_t *drv = lora_drv();
    drv->ops.ioctrl(drv, IOCTRL_SET_TX_BUFF, (uint32_t *)(&pack));

    return 0;
}

/*******************************************************************
 * 函数名: com_lora_tx_hanlder()
 * 功 能: Lora循环发送处理
 * 输 入:
 *
 * 输 出:
 *******************************************************************/
TickType_t lora_times = 0;    
void com_lora_tx_hanlder(void)
{
    /* 第一次进来赋值 */
    if(lora_times == 0)
    {
        lora_times = xTaskGetTickCount();  
    }

    /* 200ms 定时发消息给lora从机 */
    if (xTaskGetTickCount() - lora_times >= 200)
    {
        static uint8_t slave_id = 0;
        lora_times = xTaskGetTickCount();
        if (slave_id++ > 4)
        {
            slave_id = 0;
        }

        /* 按键板;需要发送控制信号 */
        uint8_t send_data = 0;
        uint8_t index = 2;

        if (slave_id == 0x00)
        {
            index = 0;
        }
        else if (slave_id == 0x03)
        {
            index = 1;
        }
        else if (slave_id == 0x01)
        {
            ;
        }
        else if (slave_id == 0x04)
        {
            ;
        }

        if (index < 2)
        {
            if (master_lora.key[index].start_ctrl == 1)
            {
                send_data |= 0x01;
            }
            else
            {
                send_data &= ~0x01;
            }

            if (master_lora.key[index].slow_ctrl == 1)
            {
                send_data |= 0x02;
            }
            else
            {
                send_data &= ~0x02;
            }

            if (master_lora.key[index].stop_ctrl == 1)
            {
                send_data |= 0x04;
            }
            else
            {
                send_data &= ~0x04;
            }
        }
        com_lora_send_cmd(slave_id, send_data);
    }
}
